package cn.anquing.rabbitmq;

import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.Map;


@Configuration
public class MQConfig {

    public static final String QUEUE = "myQueue";
    public static final String TOPIC_QUEUE1 = "topic_queue1";
    public static final String TOPIC_QUEUE2 = "topic_queue2";
    public static final String HEADER_QUEUE = "header.queue";
    public static final String TOPIC_EXCHANGE = "topicExchage";
    public static final String FANOUT_EXCHANGE = "fanoutExchage";
    public static final String HEADERS_EXCHANGE = "headersExchage";


    /******************以下都是监听者才需要配置******************/
    /**
     * Direct模式（指定模式） 交换机Exchange,生产者要指定一个queue（只能被一个消费者处理）
     * 这种模式下不需要将Exchange进行任何绑定(binding)操作
     */
    @Bean
    public Queue queue() {
        return new Queue(QUEUE, true);
    }

    /**
     * Topic模式(主题模式) 交换机Exchange,生产者指定一个TopicExchange，
     * 只要与TopicExchange绑定并routingKey能匹配得上queue会收到消息，
     * 同一queue中有多个消息者时，只会被其中一个消费者消,receiverTopic3 与 receiverTopic2 可以验证
     */
    @Bean
    public Queue topicQueue1() {
        return new Queue(TOPIC_QUEUE1, true);
    }
    @Bean
    public Queue topicQueue2() {
        return new Queue(TOPIC_QUEUE2, true);
    }
    @Bean
    public TopicExchange topicExchange(){
        return new TopicExchange(TOPIC_EXCHANGE);
    }

    /**
     * 绑定应该在监听方法上使用注解的方式
     * @return
     */
    @Bean
    public Binding topicBinding1() {
        return BindingBuilder.bind(topicQueue1()).to(topicExchange()).with("topic.key1");
    }

//    /**
//     * 绑定可以在监听方法上使用注解的方式
//     * @return
//     */
//    @Bean
//    public Binding topicBinding2() {
//        //通配符：*表示一个单词，#表示0个或多个单词
//        return BindingBuilder.bind(topicQueue2()).to(topicExchage()).with("topic.#");
//    }

    /**
     * Fanout模式（广播者模式） 交换机Exchange，生产者指定一个FanoutExchange，只要与FanoutExchange绑定的queue都能收到消息
     */
    @Bean
    public FanoutExchange fanoutExchage(){
        return new FanoutExchange(FANOUT_EXCHANGE);
    }

    @Bean
    public Binding FanoutBinding1() {
        return BindingBuilder.bind(topicQueue1()).to(fanoutExchage());
    }

    @Bean
    public Binding FanoutBinding2() {
        return BindingBuilder.bind(topicQueue2()).to(fanoutExchage());
    }
     /**
     * Header模式（头部模式） 交换机Exchange，生产者指定一个HeadersExchange,并指定一个queue，但是当头部信息匹配时才能发送信息
     */
    @Bean
    public HeadersExchange headersExchage(){
        return new HeadersExchange(HEADERS_EXCHANGE);
    }
    @Bean
    public Queue headerQueue1() {
        return new Queue(HEADER_QUEUE, true);
    }
    @Bean
    public Binding headerBinding() {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("header1", "value1");
        map.put("header2", "value2");
        return BindingBuilder.bind(headerQueue1()).to(headersExchage()).whereAll(map).match();
    }

}
